package cndw.core.dispatch.executor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;

import cndw.core.cfg.ServerConfig;

/**
 * 
 * @author zuojie.x
 */
@Component
public class ActionTaskExecutorService {
	
	/**
	 * 推荐优先使用的队列
	 */
	private volatile ActionExecutor<ActionTask> recommendTaskQueue = null;
	private List<ActionExecutor<ActionTask>> queues = new ArrayList<ActionExecutor<ActionTask>>();
	private ConcurrentHashMap<String, ActionExecutor<ActionTask>> queueMap = new ConcurrentHashMap<String, ActionExecutor<ActionTask>>();
	
	{
		int queueSize = ServerConfig.BUSINESS_THREADS > 0 ? ServerConfig.BUSINESS_THREADS
				: Runtime.getRuntime().availableProcessors() * 2;
		for (int i = 0; i < queueSize; i ++) {
			queues.add(new ActionExecutor<ActionTask>());
		}
		recommendTaskQueue = queues.get(0);
	}
	
	/**
	 * 删除指定的玩家Id与队列的关联
	 * @param playerId
	 */
	void remove(String playerId) {
		ActionExecutor<ActionTask> queue = queueMap.remove(playerId);
		if (queue != null) {
			queue.remove(playerId);
			findRecommendTaskQueue();
		}
	}
	
	/**
	 * 提交一个任务到相关联的任务队列的尾部
	 * @param actionTask
	 */
	public void submit(ActionTask actionTask) {
		selectJoinQueue(actionTask, false); 
	}
	
	/**
	 * 提交一个任务到相关联的任务队列的开头
	 * @param actionTask
	 */
	public void submitFirst(ActionTask actionTask) {
		selectJoinQueue(actionTask, true);
	}
	
	/**
	 * 选择加入到相关联的任务队列
	 * @param actionTask
	 * @param toFirst
	 */
	void selectJoinQueue(ActionTask actionTask, boolean toFirst) {
		ActionExecutor<ActionTask> queue = queueMap.get(actionTask.getPlayerId());
		if (queue == null) {
			queue = recommendTaskQueue;
			queueMap.putIfAbsent(actionTask.getPlayerId(), queue);
			if (toFirst)
				queue.executeFirst(actionTask);
			else
				queue.execute(actionTask);
			findRecommendTaskQueue();
		} else {
			if (toFirst)
				queue.executeFirst(actionTask);
			else
				queue.execute(actionTask);
		}
	}
	
	/**
	 * 找出一个推荐优先使用的队列
	 */
	void findRecommendTaskQueue() {
		int old = recommendTaskQueue.playerSize();
		for (ActionExecutor<ActionTask> actionTask : queues) {
			if (actionTask.playerSize() < old) {
				recommendTaskQueue = actionTask;
			}
		}
	}
}
